#include "xlArray.h"
#include "xlList.h"
#include "xlSet.h"
#include "xlMap.h"
#include "xlString.h"

#include <stdio.h>
#include <tchar.h>
#include <conio.h>
#include <time.h>

#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>

#define VECTOR_MAX	10000000
#define DEQUE_MAX	10000000
#define LIST_MAX	10000000
#define RBTREE_MAX	10000000


void std_vector_pushback()
{
	printf("Call std::vector::push_back %d times: ", VECTOR_MAX);
	std::vector<int> std_vec;

	clock_t start = clock();

	for (int i = 0; i < VECTOR_MAX; ++i)
	{
		std_vec.push_back(i);
	}

	clock_t end = clock();

	printf("%lfs\n", (double)(end-start) / CLK_TCK);
}

void xl_array_pushback()
{
	printf("Call xl::Array::Push_Back %d times: ", VECTOR_MAX);
	xl::Array<int> xl_arr;

	clock_t start = clock();

	for (int i = 0; i < VECTOR_MAX; ++i)
	{
		xl_arr.PushBack(i);
	}

	clock_t end = clock();

	printf("%lfs\n", (double)(end-start) / CLK_TCK);
}

void std_deque_pushfront()
{
	printf("Call std::deque::push_front %d times: ", DEQUE_MAX);
	std::deque<int> std_deq;

	clock_t start = clock();

	for (int i = 0; i < DEQUE_MAX; ++i)
	{
		std_deq.push_front(i);
	}

	clock_t end = clock();

	printf("%lfs\n", (double)(end-start) / CLK_TCK);
}

void xl_array_pushfront()
{
	printf("Call xl::Array::Push_Front %d times: ", DEQUE_MAX);
	xl::Array<int> xl_arr;

	clock_t start = clock();

	for (int i = 0; i < DEQUE_MAX; ++i)
	{
		xl_arr.PushFront(i);
	}

	clock_t end = clock();

	printf("%lfs\n", (double)(end-start) / CLK_TCK);
}

void std_list_pushback()
{
	printf("Call std::list::push_back %d times: ", LIST_MAX);
	std::list<int> std_list;

	clock_t start = clock();

	for (int i = 0; i < LIST_MAX; ++i)
	{
		std_list.push_back(i);
	}

	clock_t end = clock();

	printf("%lfs\n", (double)(end-start) / CLK_TCK);
}

void xl_list_pushback()
{
	printf("Call xl::List::Push_Back %d times: ", LIST_MAX);
	xl::List<int> xl_list;

	clock_t start = clock();

	for (int i = 0; i < LIST_MAX; ++i)
	{
		xl_list.PushBack(i);
	}

	clock_t end = clock();

	printf("%lfs\n", (double)(end-start) / CLK_TCK);
}

void std_set_insert()
{
	printf("Call std::set::insert %d times: ", RBTREE_MAX);
	std::set<int> std_set;

	clock_t start = clock();

	for (int i = 0; i < RBTREE_MAX; ++i)
	{
		std_set.insert(i);
	}

	clock_t end = clock();

	printf("%lfs\n", (double)(end-start) / CLK_TCK);
}

void xl_set_insert()
{
	printf("Call xl::Set::Insert %d times: ", RBTREE_MAX);
	xl::Set<int> xl_set;

	clock_t start = clock();

	for (int i = 0; i < RBTREE_MAX; ++i)
	{
		xl_set.Insert(i);
	}

	clock_t end = clock();

	printf("%lfs\n", (double)(end-start) / CLK_TCK);
}

void std_map_insert()
{
	printf("Call std::map::insert %d times: ", RBTREE_MAX);
	std::map<int, int> std_map;

	clock_t start = clock();

	for (int i = 0; i < RBTREE_MAX; ++i)
	{
		std_map.insert(std::make_pair(i, i));
	}

	clock_t end = clock();

	printf("%lfs\n", (double)(end-start) / CLK_TCK);
}

void xl_map_insert()
{
	printf("Call xl::Map::Insert %d times: ", RBTREE_MAX);
	xl::Map<int, int> xl_map;

	clock_t start = clock();

	for (int i = 0; i < RBTREE_MAX; ++i)
	{
		xl_map.Insert(xl::Pair<int, int>(i, i));
	}

	clock_t end = clock();

	printf("%lfs\n", (double)(end-start) / CLK_TCK);
}

int main()
{
	using namespace xl;

	printf("Array Test:\n");
	getch();

	Array<int> arr;
	arr.PushBack(2);
	arr.PushFront(0);
	arr.Insert(1, 1);

	for (Array<int>::Iterator it = arr.Begin(); it != arr.End(); ++it)
	{
		printf("%d\n", *it);
	}

	printf("List Test:\n");
	getch();

	List<int> lst;
	lst.PushBack(1);
	lst.PushFront(0);
	lst.PushBack(2);
	lst.PushBack(3);

	for (List<int>::Iterator it = lst.Begin(); it != lst.End(); ++it)
	{
		printf("%d\n", *it);
	}

	printf("Set Test:\n");
	getch();

	Set<int> set;
	set.Insert(1);
	set.Insert(2);
	set.Insert(0);
	set.Insert(3);

	for (Set<int>::Iterator it = set.Begin(); it != set.End(); ++it)
	{
		printf("%d\n", *it);
	}

	printf("Map Test:\n");
	getch();

	Map<String, int> map;
	map.Insert(_T("First"), 1);
	map.Insert(_T("Second"), 2);
	map.Insert(_T("Third"), 3);

	for (Map<String, int>::Iterator it = map.Begin(); it != map.End(); ++it)
	{
		_tprintf(_T("%s: %d\n"), (const Char *)it->Key, it->Value);
	}

	printf("String Test:\n");
	getch();
	
	String str = _T("The quick brown fox jumps over the lazy dog.");
	_tprintf(_T("%s\n"), (const Char *)str);

	String str2 = str.Replace(_T("e"), _T("EEEE"));
	_tprintf(_T("%s\n"), (const Char *)str2);

	Array<String> strs = str.Split(_T(" "));

	for (Array<String>::Iterator it = strs.Begin(); it != strs.End(); ++it)
	{
		_tprintf(_T("%s\n"), (const Char *)*it);
	}

	printf("Compare with std::vector:\n");
	getch();

	std_vector_pushback();
	xl_array_pushback();

	printf("Compare with std::deque:\n");
	getch();

	std_deque_pushfront();
	xl_array_pushfront();

	printf("Compare with std::list:\n");
	getch();

	std_list_pushback();
	xl_list_pushback();

	printf("Compare with std::set:\n");
	getch();

	std_set_insert();
	xl_set_insert();

	printf("Compare with std::map:\n");
	getch();

	std_map_insert();
	xl_map_insert();

	getch();

	return 0;
}